﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace UnitySheet
{
    /// <summary>
    /// 表格
    /// </summary>
    public class Sheet : MonoBehaviour
    {
        [HideInInspector]
        public int sheetNumber;

        public Dictionary<AnchorPoint, Cell> cells = new Dictionary<AnchorPoint, Cell>();
        public List<List<AnchorPoint>> anchors = new List<List<AnchorPoint>>();//x,y--> ||||
        public Transform anchorParent, cellParent;
        public int xNum = 0, yNum = 0;

        /// <summary>
        /// 初始化表格
        /// </summary>
        public void CreateNewSheet()
        {
            AnchorPoint[] aps = new AnchorPoint[4];
            aps[0] = CreateOneAnchorPoint(0, 0);
            aps[1] = CreateOneAnchorPoint(1, 0);
            aps[2] = CreateOneAnchorPoint(0, 1);
            aps[3] = CreateOneAnchorPoint(1, 1);

            List<AnchorPoint> aps1 = new List<AnchorPoint>();
            aps1.Add(aps[0]);
            aps1.Add(aps[2]);
            List<AnchorPoint> aps2 = new List<AnchorPoint>();
            aps2.Add(aps[1]);
            aps2.Add(aps[3]);

            anchors.Add(aps1);
            anchors.Add(aps2);

            xNum = 2;
            yNum = 2;

            CreateOneCell(aps);
        }

        /// <summary>
        /// 此方法根据原表格数据还原一个表格
        /// </summary>
        /// <param name="anchorPoints">锚点的坐标集合</param>
        /// <param name="cellPoints">单元格的四个顶点序号集合</param>
        public void SetSheet(List<List<Vector3>> anchorPoints, int[] cellPoints)
        {
            if (cellPoints.Length % 8 != 0)
            {
                throw new System.Exception("单元格顶点集合必须为8的倍数!");
            }
            List<List<AnchorPoint>> allAnchorPoints = new List<List<AnchorPoint>>();
            for (int x = 0; x < anchorPoints.Count; x++)
            {
                List<AnchorPoint> aps = new List<AnchorPoint>();
                for (int y = 0; y < anchorPoints[x].Count; y++)
                {
                    aps.Add(CreateOneAnchorPoint(x, y, anchorPoints[x][y]));
                }
                allAnchorPoints.Add(aps);
            }
            anchors = allAnchorPoints;
            xNum = anchorPoints.Count;
            yNum = anchorPoints[0].Count;

            for (int i = 0; i < cellPoints.Length; i += 8)
            {
                AnchorPoint[] aps = new AnchorPoint[4];
                aps[0] = anchors[cellPoints[i]][cellPoints[i + 1]];
                aps[1] = anchors[cellPoints[i + 2]][cellPoints[i + 3]];
                aps[2] = anchors[cellPoints[i + 4]][cellPoints[i + 5]];
                aps[3] = anchors[cellPoints[i + 6]][cellPoints[i + 7]];
                CreateOneCell(aps);
            }

        }
        public void DestroySheet()
        {
            SheetManager.sheetManager.OnDestroyOneSheet(this);
            Destroy(gameObject);
        }
        /// <summary>
        /// 添加一行
        /// </summary>
        public void AddRow()
        {
            for (int x = 0; x < xNum; x++)
            {
                AnchorPoint newAP = CreateOneAnchorPoint(x, yNum, anchors[x][anchors[x].Count - 1]);

                anchors[x].Add(newAP);
            }
            yNum += 1;
            if (yNum >= 2 && xNum >= 2)
            {
                for (int x = 0; x < xNum - 1; x++)
                {
                    AnchorPoint[] aps = new AnchorPoint[4];
                    aps[0] = anchors[x][yNum - 2];
                    aps[1] = anchors[x + 1][yNum - 2];
                    aps[2] = anchors[x][yNum - 1];
                    aps[3] = anchors[x + 1][yNum - 1];
                    CreateOneCell(aps);
                }
            }
        }

        /// <summary>
        /// 添加一列
        /// </summary>
        public void AddColumn()
        {
            List<AnchorPoint> newColumnPoints = new List<AnchorPoint>();
            for (int y = 0; y < yNum; y++)
            {
                AnchorPoint newAP = CreateOneAnchorPoint(xNum, y, anchors[xNum - 1][y]);
                newColumnPoints.Add(newAP);
            }
            anchors.Add(newColumnPoints);
            xNum += 1;
            if (yNum >= 2 && xNum >= 2)
            {
                for (int y = 0; y < yNum - 1; y++)
                {
                    AnchorPoint[] aps = new AnchorPoint[4];
                    aps[0] = anchors[xNum - 2][y];
                    aps[1] = anchors[xNum - 1][y];
                    aps[2] = anchors[xNum - 2][y + 1];
                    aps[3] = anchors[xNum - 1][y + 1];
                    CreateOneCell(aps);
                }
            }
        }


        #region//删除功能
        /// <summary>
        /// 删除行
        /// </summary>
        public void DeleteRowCells(Cell cell)
        {
            if (yNum <= cell.cellHeight + 1)
            {
                DestroySheet();
                return;
            }
            int h = cell.cellHeight;
            float posHeight = cell.anchorPoints[0].transform.position.y - cell.anchorPoints[2].transform.position.y;
            AnchorPoint anchorStart = cell.anchorPoints[0];
            List<Cell> dcs = new List<Cell>();
            for (int x = 0; x < xNum; x++)
            {
                for (int y = anchorStart.y; y < anchorStart.y + h; y++)
                {
                    //可能被删除的单元格
                    if (cells.ContainsKey(anchors[x][y]))
                    {
                        dcs.Add(cells[anchors[x][y]]);
                        cells.Remove(anchors[x][y]);
                    }
                    //替换锚点
                    Cell[] cs = anchors[x][y].GetMyCells();
                    for (int i = 0; i < cs.Length; i++)
                    {
                        cs[i].ReplaceAchor(anchors[x][y], anchors[x][anchorStart.y + h]);
                    }
                }
            }
            //删除单元格
            int dcscount = dcs.Count;
            for (int i = 0; i < dcscount; i++)
            {
                if (dcs[0].cellHeight <= 0)
                {
                    DestroyCell(dcs[0]);
                }
                else
                {
                    //cells.Remove(anchors[dcs[index].anchorPoints[0].x][anchorStart.y]);
                    //cells.Add(dcs[index].anchorPoints[0], dcs[index]);
                }
                dcs.RemoveAt(0);
            }

            int startIndex = anchorStart.y;
            //删除行
            for (int i = 0; i < h; i++)
            {
                DeleteRowAnchors(anchorStart.y + i);
            }
            for (int i = 0; i < xNum; i++)
            {
                for (int j = startIndex; j < yNum; j++)
                {
                    Vector3 newPos = anchors[i][j].transform.position;
                    newPos.y += posHeight;
                    anchors[i][j].Move(newPos);
                }
            }
        }

        /// <summary>
        /// 删除一列
        /// </summary>
        public void DeleteColumnCells(Cell cell)
        {
            if (xNum <= cell.cellWidth + 1)
            {
                DestroySheet();
                return;
            }
            int w = cell.cellWidth;
            float posWidth = cell.anchorPoints[1].transform.position.x - cell.anchorPoints[0].transform.position.x;
            AnchorPoint anchorStart = cell.anchorPoints[0];
            List<Cell> dcs = new List<Cell>();

            for (int x = anchorStart.x; x < anchorStart.x + w; x++)
            {
                for (int y = 0; y < yNum; y++)
                {
                    //可能被删除的单元格
                    if (cells.ContainsKey(anchors[x][y]))
                    {
                        dcs.Add(cells[anchors[x][y]]);
                        cells.Remove(anchors[x][y]);
                    }
                    //替换锚点
                    Cell[] cs = anchors[x][y].GetMyCells();
                    for (int i = 0; i < cs.Length; i++)
                    {
                        cs[i].ReplaceAchor(anchors[x][y], anchors[anchorStart.x + w][y]);
                    }

                }
            }

            //删除单元格
            int dcscount = dcs.Count;
            for (int i = 0; i < dcscount; i++)
            {
                if (dcs[0].cellWidth <= 0)
                {
                    DestroyCell(dcs[0]);
                }
                else
                {
                    //cells.Remove(anchors[dcs[index].anchorPoints[0].x][anchorStart.y]);
                    //cells.Add(dcs[index].anchorPoints[0], dcs[index]);
                }
                dcs.RemoveAt(0);
            }

            int startIndex = anchorStart.x;
            //删除列
            for (int i = 0; i < w; i++)
            {
                DeleteColumnAnchors(anchorStart.x + i);
            }
            for (int i = startIndex; i < xNum; i++)
            {
                for (int j = 0; j < yNum; j++)
                {
                    Vector3 newPos = anchors[i][j].transform.position;
                    newPos.x -= posWidth;
                    anchors[i][j].Move(newPos);
                }
            }
        }
        /// <summary>
        /// 删除一行锚点
        /// </summary>
        /// <param name="rowIndex"></param>
        public void DeleteRowAnchors(int rowIndex)
        {
            for (int i = 0; i < xNum; i++)
            {
                for (int j = rowIndex; j < yNum; j++)
                {
                    anchors[i][j].y -= 1;
                }
                Destroy(anchors[i][rowIndex].gameObject);
                anchors[i].RemoveAt(rowIndex);
            }
            yNum -= 1;
        }
        public void DeleteColumnAnchors(int columnIndex)
        {
            for (int i = 0; i < yNum; i++)
            {
                Destroy(anchors[columnIndex][i].gameObject);
            }
            anchors.RemoveAt(columnIndex);
            for (int i = columnIndex; i < anchors.Count; i++)
            {
                for (int j = 0; j < yNum; j++)
                {
                    anchors[i][j].x -= 1;
                }
            }
            xNum -= 1;
        }

        #endregion

        /// <summary>
        /// 插入行
        /// </summary>
        public void InsertRowAnchorPoints(List<List<AnchorPoint>> rows, int startY)
        {
            for (int x = 0; x < xNum; x++)
            {
                for (int y = startY + 1; y < yNum; y++)
                {
                    anchors[x][y].y += rows[0].Count;
                }
                anchors[x].InsertRange(startY + 1, rows[x]);
            }
            yNum += rows[0].Count;
        }
        /// <summary>
        /// 插入列
        /// </summary>
        /// <param name="startX"></param>
        /// <param name="num"></param>
        public void InsertColumnAnchorPoints(List<List<AnchorPoint>> columns, int startX)
        {
            for (int i = startX + 1; i < xNum; i++)
            {
                for (int j = 0; j < yNum; j++)
                {
                    anchors[i][j].x += columns.Count;
                }
            }
            xNum += columns.Count;
            anchors.InsertRange(startX + 1, columns);
        }

        #region 创建锚点
        public AnchorPoint CreateOneAnchorPoint(int x, int y)
        {
            AnchorPoint newAP = AnchorPoint.CreateOneAnchorPoint(x, y, this);
            newAP.transform.SetParent(anchorParent);
            newAP.onDrag += OnAnchorPointMove;
            return newAP;
        }
        public AnchorPoint CreateOneAnchorPoint(int x, int y, AnchorPoint prevAnchor)
        {
            AnchorPoint newAP = AnchorPoint.CreateOneAnchorPoint(x, y, this, prevAnchor);
            newAP.transform.SetParent(anchorParent);
            newAP.onDrag += OnAnchorPointMove;
            return newAP;
        }
        public AnchorPoint CreateOneAnchorPoint(int x, int y, Vector3 pos)
        {
            AnchorPoint newAP = AnchorPoint.CreateOneAnchorPoint(x, y, this, pos);
            newAP.transform.SetParent(anchorParent);
            newAP.onDrag += OnAnchorPointMove;
            return newAP;
        }
        #endregion

        /// <summary>
        /// 创建出新的单元格时
        /// </summary>
        /// <param name="newCell"></param>
        public Cell CreateOneCell(AnchorPoint[] anchorPoints)
        {
            if (anchorPoints.Length != 4)
            {
                throw new System.Exception("组成单元格的锚点必须为4个！");
            }
            Cell newCell = Cell.CreateOneCell(anchorPoints, this);
            cells.Add(newCell.anchorPoints[0], newCell);
            newCell.onSelectOneCell += SheetManager.sheetManager.sheetOperator.OnSelectOneCell;
            newCell.onDeselectOneCell += SheetManager.sheetManager.sheetOperator.OnDeselectOneCell;
            newCell.transform.SetParent(cellParent);
            return newCell;
        }

        public void DestroyCell(Cell cell)
        {
            if (cells.ContainsValue(cell))
            {
                cells.Remove(cell.anchorPoints[0]);
            }
            cell.DestroyCell();
        }

        protected void OnAnchorPointMove(AnchorPoint anchorPoint)
        {
            for (int x = 0; x < anchors.Count; x++)
            {
                anchors[x][anchorPoint.y].SyncAnchorPoint(anchorPoint);
            }
            for (int y = 0; y < anchors[anchorPoint.x].Count; y++)
            {
                anchors[anchorPoint.x][y].SyncAnchorPoint(anchorPoint);
            }
        }
    }
}
